package cn.zcltd.btg.validjsonq;

import cn.zcltd.btg.sutil.EmptyUtil;
import cn.zcltd.btg.validq.ValidQ;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

/**
 * 核心的基于json规则验证的验证器装载器
 */
public class ValidJsonQCoreLoader implements ValidJsonQLoader {

    @Override
    public void loadObject(ValidQ validQ, String group, JSONObject config, JSONObject data, String parentField, String parentFieldName, Integer level) {
        boolean ignoreGroup = null == group || "".equals(group.trim());
        parentField = null == parentField || parentField.trim().length() == 0 ? "" : parentField;
        parentFieldName = null == parentFieldName || parentFieldName.trim().length() == 0 ? "" : parentFieldName;
        level = null == level ? 1 : level + 1;

        if (null == data || data.size() == 0) {
            data = new JSONObject();
        }

        for (String key : config.keySet()) {
            JSONObject field = config.getJSONObject(key);
            if (null == field || field.size() == 0) {//key对应的value为null或为空对象，跳过该字段
                continue;
            }

            /*
                基础属性
             */
            String attrShortField = key;
            String attrField = parentField + (parentField.length() == 0 ? "" : ".") + attrShortField;
            String attrShortFieldName = field.getString("name");
            if (null == attrShortFieldName || attrShortFieldName.trim().length() == 0) {
                attrShortFieldName = attrShortField;
            }
            String attrFieldName = parentFieldName + (parentFieldName.length() == 0 ? "" : ".") + attrShortFieldName;

            /*
                解析验证器
             */
            JSONObject valid = field.getJSONObject("valid");
            if (null != valid && valid.size() != 0) {//valid为null或为空对象，无需验证
                for (String validKey : valid.keySet()) {
                    JSONObject validationConfig = valid.getJSONObject(validKey);
                    if (null != validationConfig && validationConfig.size() != 0) {
                        Boolean validatorEnable = validationConfig.getBoolean("enable");
                        if (null == validatorEnable) {
                            validatorEnable = true;
                        }
                        String validatorGroup = validationConfig.getString("group");
                        if (null == validatorGroup || validatorGroup.trim().equals("")) {
                            validatorGroup = group;
                        }
                        if (validatorEnable && (ignoreGroup || validatorGroup.equals(group))) {
                            Object target = data.get(key);
                            Integer validatorLevel = validationConfig.getInteger("level");
                            level = EmptyUtil.isEmpty(validatorLevel) ? level : validatorLevel;
                            Integer validatorIndex = validationConfig.getInteger("index");
                            ValidQElement element = ValidQMapper.me.get(validKey);
                            element.getValidatorLoader().load(validQ, validationConfig, target, attrField, attrShortField, attrFieldName, attrShortFieldName, level, validatorIndex);
                        }
                    }
                }
            }

            /*
                处理下级验证
             */
            JSONObject childConfig = field.getJSONObject("childValid");
            if (null == childConfig || childConfig.size() == 0) {
                continue;
            }

            //字段类型
            String type = field.getString("type");
            if (null == type || type.trim().length() == 0) {
                type = DataType.STRING.getType();
            }

            switch (DataType.parse(type)) {
                case OBJECT:
                    loadObject(validQ, group, childConfig, data.getJSONObject(key), attrField, attrFieldName, level);
                    break;
                case LIST:
                    loadList(validQ, group, childConfig, data.getJSONArray(key), attrField, attrFieldName, level);
                    break;
                case ARRAY:
                    loadArray(validQ, group, childConfig, data.getJSONArray(key), attrField, attrFieldName, level);
                    break;
            }
        }
    }

    @Override
    public void loadList(ValidQ validQ, String group, JSONObject config, JSONArray data, String parentField, String parentFieldName, Integer level) {
        parentField = null == parentField || parentField.trim().length() == 0 ? "" : parentField;
        parentFieldName = null == parentFieldName || parentFieldName.trim().length() == 0 ? "" : parentFieldName;
        level = null == level ? 1 : level + 1;

        if (null == data || data.size() == 0) {
            data = new JSONArray();
        }

        for (int i = 0, l = data.size(); i < l; i++) {
            JSONObject childData4List = data.getJSONObject(i);

            String attrField = String.format("%s[%s]", parentField, i);
            String attrFieldName;
            if (parentFieldName.equals(parentField)) {
                attrFieldName = attrField;
            } else {
                attrFieldName = String.format("%s[第%s条]", parentFieldName, i + 1);
            }

            loadObject(validQ, group, config, childData4List, attrField, attrFieldName, level);
        }
    }

    @Override
    public void loadArray(ValidQ validQ, String group, JSONObject config, JSONArray data, String parentField, String parentFieldName, Integer level) {
        boolean ignoreGroup = null == group || "".equals(group.trim());
        parentField = null == parentField || parentField.trim().length() == 0 ? "" : parentField;
        parentFieldName = null == parentFieldName || parentFieldName.trim().length() == 0 ? "" : parentFieldName;
        level = null == level ? 1 : level + 1;

        if (null == data || data.size() == 0) {
            data = new JSONArray();
        }

        for (int i = 0, l = data.size(); i < l; i++) {
            String attrShortField = String.format("[%s]", i);
            String attrField = parentField + attrShortField;
            String attrShortFieldName;
            if (parentFieldName.equals(parentField)) {
                attrShortFieldName = attrShortField;
            } else {
                attrShortFieldName = String.format("[第%s条]", i + 1);
            }
            String attrFieldName = parentFieldName + attrShortFieldName;

            /*
                解析验证器
             */
            JSONObject valid = config.getJSONObject("valid");
            if (null != valid && valid.size() != 0) {//valid为null或为空对象，无需验证
                for (String validKey : valid.keySet()) {
                    JSONObject validationConfig = valid.getJSONObject(validKey);
                    if (null != validationConfig && validationConfig.size() != 0) {
                        Boolean validatorEnable = validationConfig.getBoolean("enable");
                        if (null == validatorEnable) {
                            validatorEnable = true;
                        }
                        String validatorGroup = validationConfig.getString("group");
                        if (null == validatorGroup || validatorGroup.trim().equals("")) {
                            validatorGroup = group;
                        }
                        if (validatorEnable && (ignoreGroup || validatorGroup.equals(group))) {
                            Object target = data.get(i);
                            Integer validatorLevel = validationConfig.getInteger("level");
                            level = EmptyUtil.isEmpty(validatorLevel) ? level : validatorLevel;
                            Integer validatorIndex = validationConfig.getInteger("index");
                            validatorIndex = null == validatorIndex ? 1 : validatorIndex;
                            ValidQElement element = ValidQMapper.me.get(validKey);
                            element.getValidatorLoader().load(validQ, validationConfig, target, attrField, attrShortField, attrFieldName, attrShortFieldName, level, validatorIndex);
                        }
                    }
                }
            }

            /*
                处理下级验证
             */
            JSONObject childConfig = config.getJSONObject("childValid");
            if (null == childConfig || childConfig.size() == 0) {
                continue;
            }

            //字段类型
            String type = config.getString("type");
            if (null == type || type.trim().length() == 0) {
                type = DataType.STRING.getType();
            }

            switch (DataType.parse(type)) {
                case OBJECT:
                    loadObject(validQ, group, childConfig, data.getJSONObject(i), attrField, attrFieldName, level);
                    break;
                case LIST:
                    loadList(validQ, group, childConfig, data.getJSONArray(i), attrField, attrFieldName, level);
                    break;
                case ARRAY:
                    loadArray(validQ, group, childConfig, data.getJSONArray(i), attrField, attrFieldName, level);
                    break;
            }
        }
    }
}